package com.gitee.wsl.android.ui.recyclerView

import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.gitee.wsl.android.ui.recyclerView.callback.DragAndSwipeDataCallback
import com.gitee.wsl.android.ui.recyclerView.callback.DragAndSwipeHelper
import com.gitee.wsl.android.ui.recyclerView.callback.OnItemDragListener
import com.gitee.wsl.android.ui.recyclerView.callback.OnItemSwipeListener
import com.gitee.wsl.android.ui.recyclerView.itemDecoration.DecorationScope
import com.gitee.wsl.android.ui.recyclerView.itemDecoration.GridDecorationScope
import com.gitee.wsl.android.ui.recyclerView.itemDecoration.LineDecorationScope
import com.gitee.wsl.android.ui.recyclerView.itemDecoration.StaggeredGridDecorationScope
import com.gitee.wsl.android.ui.recyclerView.itemDecoration.builder.XGridBuilder
import com.gitee.wsl.android.ui.recyclerView.itemDecoration.builder.XLinearBuilder
import com.gitee.wsl.android.ui.recyclerView.itemDecoration.builder.XStaggeredGridBuilder
import com.gitee.wsl.android.ui.recyclerView.sample.stick.StickItemModule
import com.gitee.wsl.android.ui.recyclerView.sample.stick.setupStickItemModule
import com.gitee.wsl.android.ui.recyclerView.sample.zoom.ZoomRecyclerLayout
import com.gitee.wsl.ext.any.nullSet

interface LayoutScope<L:RecyclerView.LayoutManager,D: DecorationScope<*>>{
   fun config(configLayout:L.()->Unit)
   fun itemDecoration(configDecoration:D.()->Unit)
}

interface LinearLayoutScope:LayoutScope<LinearLayoutManager, LineDecorationScope>{
    fun stick(predicate: StickItemModule.StickItemPredicate)
}

interface ZoomLayoutScope:LayoutScope<ZoomRecyclerLayout, LineDecorationScope>{}

interface GridLayoutScope:LayoutScope<GridLayoutManager, GridDecorationScope>{}

interface StaggeredGridLayoutScope:LayoutScope<StaggeredGridLayoutManager, StaggeredGridDecorationScope>{}


interface RecyclerViewConfigScope{

   fun config(config:RecyclerView.()->Unit)

   fun itemDragAndDrop(dataCallback: DragAndSwipeDataCallback, listener: OnItemDragListener)

   fun itemSwipe(listener: OnItemSwipeListener)

   fun linearLayout(configLayout:LinearLayoutScope.()->Unit)

   fun gridLayout(configLayout:GridLayoutScope.()->Unit)

   fun staggerGridLayout(configLayout: StaggeredGridLayoutScope.()->Unit)

   fun zoomLayout(configLayout:ZoomLayoutScope.()->Unit)

}

fun <VH,ADAPTER:RecyclerView.Adapter<VH>> RecyclerView.sampleConfig(adapter:ADAPTER,config:RecyclerViewConfigScope.()->Unit){
    var dragAndSwipeHelper: DragAndSwipeHelper?= null
    val scope = object:RecyclerViewConfigScope{
        override fun config(config: RecyclerView.() -> Unit) {
            config(this)
        }

     override fun itemDragAndDrop(dataCallback: DragAndSwipeDataCallback, listener: OnItemDragListener) {
          dragAndSwipeHelper.nullSet { dragAndSwipeHelper = DragAndSwipeHelper() }
          dragAndSwipeHelper?.setDataCallback(dataCallback)
          dragAndSwipeHelper?.setItemDragListener(listener)
      }

      override fun itemSwipe(listener: OnItemSwipeListener) {
          dragAndSwipeHelper.nullSet { dragAndSwipeHelper = DragAndSwipeHelper() }
          dragAndSwipeHelper?.setItemSwipeListener(listener)
      }

        override fun linearLayout(configLayout: LinearLayoutScope.() -> Unit) {
            val layoutManager=LinearLayoutManager(context, LinearLayoutManager.VERTICAL,false)
            val scope=object:LinearLayoutScope{
                override fun stick(predicate: StickItemModule.StickItemPredicate) {
                    setupStickItemModule(adapter, predicate)
                }

                override fun config(configLayout: LinearLayoutManager.() -> Unit) {
                    configLayout(layoutManager)
                }

                override fun itemDecoration(configDecoration: LineDecorationScope.() -> Unit) {
                    val decorationBuilder = XLinearBuilder(context)
                    configDecoration(object: LineDecorationScope {
                        override fun config(builder: XLinearBuilder.() -> Unit) {
                            builder(decorationBuilder)
                        }
                    })
                    addItemDecoration(decorationBuilder.build())
                }
            }
            configLayout(scope)
            setLayoutManager(layoutManager)

        }

        override fun gridLayout(configLayout: GridLayoutScope.() -> Unit) {
            val layoutManager=GridLayoutManager(context,1, LinearLayoutManager.VERTICAL,false)
            val scope=object:GridLayoutScope{
                override fun config(configLayout: GridLayoutManager.() -> Unit) {
                    configLayout(layoutManager)
                }
                override fun itemDecoration(configDecoration: GridDecorationScope.() -> Unit) {
                    val decorationBuilder = XGridBuilder(context)
                    configDecoration(object: GridDecorationScope {
                        override fun config(builder: XGridBuilder.() -> Unit) {
                            builder(decorationBuilder)
                        }
                    })
                    addItemDecoration(decorationBuilder.build())
                }
            }
            configLayout(scope)
            setLayoutManager(layoutManager)
        }

        override fun staggerGridLayout(configLayout: StaggeredGridLayoutScope.() -> Unit) {
            val layoutManager=StaggeredGridLayoutManager(3, LinearLayoutManager.VERTICAL)
            val scope=object:StaggeredGridLayoutScope{
                override fun config(configLayout: StaggeredGridLayoutManager.() -> Unit) {
                    configLayout(layoutManager)
                }

                override fun itemDecoration(configDecoration: StaggeredGridDecorationScope.() -> Unit) {
                    val decorationBuilder = XStaggeredGridBuilder(context)
                    configDecoration(object: StaggeredGridDecorationScope {
                        override fun config(builder: XStaggeredGridBuilder.() -> Unit) {
                            builder(decorationBuilder)
                        }
                    })
                    addItemDecoration(decorationBuilder.build())
                }

            }
            configLayout(scope)
            setLayoutManager(layoutManager)
        }

        override fun zoomLayout(configLayout: ZoomLayoutScope.() -> Unit) {
            val layoutManager= ZoomRecyclerLayout(context, LinearLayoutManager.VERTICAL,false)
            val scope=object:ZoomLayoutScope{

                override fun config(configLayout: ZoomRecyclerLayout.() -> Unit) {
                    configLayout(layoutManager)
                }

                override fun itemDecoration(configDecoration: LineDecorationScope.() -> Unit) {
                    val decorationBuilder = XLinearBuilder(context)
                    configDecoration(object: LineDecorationScope {
                        override fun config(builder: XLinearBuilder.() -> Unit) {
                            builder(decorationBuilder)
                        }
                    })
                    addItemDecoration(decorationBuilder.build())
                }
            }
            configLayout(scope)
            setLayoutManager(layoutManager)
        }
    }
    config(scope)
    dragAndSwipeHelper?.attachToRecyclerView(this)
    setAdapter(adapter)
}